package com.soft.sitegenerator.ftp;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

final class FtpUploader implements Runnable {
	private final UploadFrame applet;

	protected FTPClient ftp;

	/**
	 * @param applet
	 */
	public FtpUploader(UploadFrame applet) {
		this.applet = applet;
	}

	public volatile Object semaphor;

	public void runFtp() {
		try {
			this.ftp = new FTPClient();
			int reply;
			this.applet.setStatusText(I18NMessages
					.getString("FtpUploader.Connecting"));
			this.ftp.connect(FtpParameters.getHost());
			this.applet.setStatusText(I18NMessages
					.getString("FtpUploader.Connected_to")
					+ FtpParameters.getHost());
			System.out.print(this.ftp.getReplyString());

			// After connection attempt, you should check the reply code to
			// verify
			// success.
			reply = this.ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				this.ftp.disconnect();
				this.applet.setStatusText(I18NMessages
						.getString("FtpUploader.Connection_refused"));
			} else {
				if (!this.ftp.login(FtpParameters.getUsername(), FtpParameters
						.getPassword())) {
					this.applet.setStatusText(I18NMessages
							.getString("FtpUploader.Server_auth_failed"));
				}
				if (!FTPReply.isPositiveCompletion(this.ftp.cwd(FtpParameters
						.getUploadFolder()))) {
					throw new IOException();
				}

				// Upload files
				DefaultTreeModel model = (DefaultTreeModel) this.applet.jItemsTree
						.getModel();
				DefaultMutableTreeNode root = (DefaultMutableTreeNode) model
						.getRoot();
				Enumeration nodesEnum = root.children();
				getDir(nodesEnum);

				// Disconnect when done
				this.applet.setStatusText(I18NMessages
						.getString("FtpUploader.Disconnecting..."));
				this.ftp.logout();
				this.applet.setStatusText(I18NMessages
						.getString("FtpUploader.Disconnected"));
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			this.applet.enableUpload();
			if (this.ftp.isConnected()) {
				try {
					this.ftp.disconnect();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			}
		}
	}

	public void getDir(Enumeration nodes) throws IOException,
			InterruptedException {
		DefaultMutableTreeNode node;
		while (nodes.hasMoreElements()) {
			node = (DefaultMutableTreeNode) nodes.nextElement();
			TreeElement el = (TreeElement) node.getUserObject();
			File file = el.getFile();
			if (file.isFile()) {
				// Is a file:
				this.doUploadFile(file);
			}
			if (file.isDirectory()) {
				// Is a directory
				Enumeration nodes2 = node.children();
				this.ftp.makeDirectory(file.getName());
				this.ftp.cwd(file.getName());
				this.getDir(nodes2);

				this.ftp.cwd("../");
			}
		}
	}

	protected void doUploadFile(File file) throws IOException,
			InterruptedException {

		this.applet.setStatusText(I18NMessages
				.getString("FtpUploader.Uploading")
				+ " " + file.getName() + "...");

		BufferedInputStream imgStream = new BufferedInputStream(
				new FileInputStream(file.getAbsolutePath()));
		this.ftp.setFileType(FTP.BINARY_FILE_TYPE);
		OutputStream outputStream = this.ftp.storeFileStream(file.getName());

		try {
			int total = imgStream.available();
			this.applet.jProgressBar.setMaximum(total);
			byte[] b = new byte[1];
			int count = 0;
			int c;
			while ((c = imgStream.read(b)) != -1) {
				count += c;
				this.applet.jProgressBar.setValue(count);
				outputStream.write(b);
			}
			this.applet.jProgressBar.setValue(this.applet.jProgressBar
					.getMaximum());
			this.applet.setStatusText("File " + file.getName()
					+ I18NMessages.getString("FtpUploader._transferred"));
		} finally {
			imgStream.close();
			outputStream.close();
			if (!this.ftp.completePendingCommand()) {
				throw new IOException();
			}

		}
	}

	public void run() {
		runFtp();
	}
}